package cc.rengu.igas.bsps.core.service.trans;

import cc.rengu.igas.bsps.common.constant.BspsAppParamConstant;
import cc.rengu.igas.bsps.common.constant.BspsTreeNodeConstant;
import cc.rengu.igas.bsps.common.dao.AlipayMchntInfoMapper;
import cc.rengu.igas.bsps.common.dao.CupsMchntInfoMapper;
import cc.rengu.igas.bsps.common.dao.WechatMchntInfoMapper;
import cc.rengu.igas.bsps.common.dao.impl.AlipayMchntInfoMapperImpl;
import cc.rengu.igas.bsps.common.dao.impl.CupsMchntInfoMapperImpl;
import cc.rengu.igas.bsps.common.dao.impl.WechatMchntInfoMapperImpl;
import cc.rengu.igas.bsps.common.entity.AlipayMchntInfo;
import cc.rengu.igas.bsps.common.entity.CupsMchntInfo;
import cc.rengu.igas.bsps.common.entity.WechatMchntInfo;
import cc.rengu.igas.bsps.common.enums.BspsPayTypeEnum;
import cc.rengu.igas.bsps.common.enums.MchntTypeEnum;
import cc.rengu.igas.bsps.common.enums.RespCodeEnum;
import cc.rengu.igas.bsps.core.service.base.PayService;
import cc.rengu.igas.bsps.facade.base.Header;
import cc.rengu.igas.bsps.facade.bean.OrderInfoBean;
import cc.rengu.igas.bsps.facade.request.ScanQrCodeReceiptsRequest;
import cc.rengu.igas.bsps.facade.response.ScanQrCodeReceiptsResponse;
import cc.rengu.igas.channel.alipay.facade.response.AliMircopayResponse;
import cc.rengu.igas.channel.upqc.facade.response.C2BConsumeResponse;
import cc.rengu.igas.channel.wechat.facade.response.WechatMicropayResponse;
import cc.rengu.igas.channel.wechat.facade.result.Result;
import cc.rengu.igas.share.common.constant.ShareParamConstant;
import cc.rengu.igas.share.common.constant.TransCacheConstant;
import cc.rengu.igas.share.core.model.MchntInfo;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.oltp.service.base.ChannelBaseService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.entity.ChannelCallCfg;
import cc.rengu.oltp.service.common.entity.MchntOrderInfo;
import cc.rengu.oltp.service.common.entity.PayOrderInfo;
import cc.rengu.oltp.service.common.entity.UserOrderInfo;
import cc.rengu.oltp.service.common.enums.*;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.OrderInfo;
import cc.rengu.oltp.service.realize.OrderService;
import cc.rengu.oltp.service.realize.TransCustomImpl;
import cc.rengu.oltp.service.realize.impl.OrderServiceImpl;
import cc.rengu.oltp.utility.util.*;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 扫码收款申请服务  （目前支持 微信，支付宝，云闪付）
 * author: zhangxuran
 * Date: 2020/3/28 23:35
 */
public class ScanQrCodeReceiptsService extends PayService implements TransCustomImpl {
    @Override
    protected Object bizBeforeCust() throws Exception {
        ScanQrCodeReceiptsRequest scanQrCodeReceiptsRequest = new ScanQrCodeReceiptsRequest();
        ConvertUtil.convertOutput(scanQrCodeReceiptsRequest);
        return scanQrCodeReceiptsRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        ScanQrCodeReceiptsRequest scanQrCodeReceiptsRequest = (ScanQrCodeReceiptsRequest) request;
        String instId = scanQrCodeReceiptsRequest.getHeader().getInstId();
        String mchntNo = scanQrCodeReceiptsRequest.getMchntNo();

        /* Step1：入参金额检查 */
        String orderAmt = scanQrCodeReceiptsRequest.getOrderAmt();
        rglog.debug("订单金额：{}", orderAmt);
        orderAmt = AmountUtil.checkAmt(orderAmt, 2, false, false);
        scanQrCodeReceiptsRequest.setOrderAmt(orderAmt);

        /* Step2：获取付款二维码类型并校验业务类型 */
        String payType = getQrCodeType(scanQrCodeReceiptsRequest);
        rglog.info("付款码类型:<{}>", payType);
        if (StringUtil.isEmptyOrNull(payType)) {
            rglog.error("区分付款码类型失败！扫码收款失败！ sysSeqNum：<{}>, mchntNo:<{}>", sysSeqNum, scanQrCodeReceiptsRequest.getMchntNo());
            throw new BizException(RespCodeEnum.NOT_SUPPORT_ORT_TYPE.getRespCode(), RespCodeEnum.NOT_SUPPORT_ORT_TYPE.getRespDesc());
        }
        xmlTreeUtil.setXmlTreeStringValue("payType", payType);
        String bizType = verifyBizType(payType);
        if (!bizType.equals(scanQrCodeReceiptsRequest.getHeader().getBizType())) {
            rglog.debug("商户服务扫码支付(被扫)，传入bizType:{}，实际二维码类型为：{}，更正bizType。", scanQrCodeReceiptsRequest.getHeader().getBizType(), bizType);
            rglog.error("区分付款码类型失败！扫码收款失败！ sysSeqNum：<{}>, mchntNo:<{}>", sysSeqNum, scanQrCodeReceiptsRequest.getMchntNo());
            throw new BizException(RespCodeEnum.NOT_SUPPORT_ORT_TYPE.getRespCode(), RespCodeEnum.NOT_SUPPORT_ORT_TYPE.getRespDesc());
        }

        /* Step3：获取商户信息并校验 */
        MchntService mchntService = new MchntServiceImpl();
        MchntInfo mchntInfo = mchntService.getMchntInfo(instId, mchntNo);
        if (null == mchntInfo) {
            rglog.error("获取商户信息失败,mchntNo:<{}>", scanQrCodeReceiptsRequest.getMchntNo());
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }

        /* Step4：校验商户限额 */
        String acctType = AcctTypeEnum.ALL.getAcctType();
        if (BspsPayTypeEnum.CUPS_CLOUD_PAY.getPayType().equals(payType)) {
            acctType = xmlTreeUtil.getXmlTreeStringValue(BspsTreeNodeConstant.PAYER_ACCT_TYPE);
        }
        int iReturnCode = mchntService.checkMchntTransLimit(mchntInfo.getInstId(), scanQrCodeReceiptsRequest.getOrderAmt(), LimitAcctTypeEnum.getAcctType(acctType), mchntInfo.getMchntNo(), null, BspsAppParamConstant.BSPS_SCAN_QRCODE_TXN_NUM);
        if (0 != iReturnCode) {
            rglog.error("商户限额超限{}", mchntNo);
            throw new BizException(RespCodeEnum.MCHNT_AMT_OVER.getRespCode(), RespCodeEnum.MCHNT_AMT_OVER.getRespDesc());
        }

        /* Step5：登记用户订单和商户订单 */
        OrderInfo orderInfo = new OrderInfo();
        OrderService orderService = new OrderServiceImpl();
        UserOrderInfo userOrderInfo = initUserOrderInfo(scanQrCodeReceiptsRequest, sysSeqNum);
        MchntOrderInfo mchntOrderInfo = initMchntOrderInfo(scanQrCodeReceiptsRequest, sysSeqNum);
        List<MchntOrderInfo> mchntOrderInfoArrayList = new ArrayList<>();
        mchntOrderInfoArrayList.add(mchntOrderInfo);
        orderInfo.setUserOrderInfo(userOrderInfo);
        orderInfo.setMchntOrderInfoList(mchntOrderInfoArrayList);
        if (!orderService.registerOrderInfo(userOrderInfo, mchntOrderInfoArrayList, null)) {
            rglog.error("登记用户商户订单错误.");
            throw new BizException(RespCodeEnum.INSERT_ORDER_INFO_ERROR.getRespCode(), RespCodeEnum.INSERT_ORDER_INFO_ERROR.getRespDesc());
        }

        /* Step6：调用通道接口 */
        if (null == txnInfo.getChannelCallCfgList() || txnInfo.getChannelCallCfgList().isEmpty()) {
            rglog.error("<{}-{}>交易未配置交易通道服务调用配置信息！", txnInfo.getSrcTxnAuthCfg().getTxnNum(), txnInfo.getSrcTxnAuthCfg().getTxnName());
            throw new BizException(RespCodeEnum.CHANNEL_CONFIG_NOT_EXIST.getRespCode(), RespCodeEnum.CHANNEL_CONFIG_NOT_EXIST.getRespDesc());
        }
        List<ChannelCallCfg> channelCallCfgList = txnInfo.getChannelCallCfgList().stream().filter(item ->
                item.getCallIndex().equals(ChannelBaseService.FIRST_CHANNEL_CALL_INDEX)).collect(Collectors.toList());
        ChannelCallCfg channelCallCfg = channelCallSceneDiscern(scanQrCodeReceiptsRequest, channelCallCfgList);
        Class channelClasz = Class.forName(channelCallCfg.getCallChannelImpl());
        ChannelBaseService channelBaseService = (ChannelBaseService) channelClasz.newInstance();
        channelBaseService.callService(txnInfo, orderInfo, channelCallCfg.getBizScene(), request);

        /* Step7：更新商户累计限额 */
        if (BizStatusEnum.FINISH.getStatus().equals(orderInfo.getUserOrderInfo().getBizStatus()) &&
                OrderStatusEnum.FINISH.getStatus().equals(orderInfo.getUserOrderInfo().getOrderStatus())) {
            mchntService.updateMchntTransLimit(orderInfo.getMchntOrderInfoList());
        }

        /* Step8：组装应答报文 */
        BizResponse bizResponse = new BizResponse();
        ScanQrCodeReceiptsResponse scanQrCodeReceiptsResponse = (ScanQrCodeReceiptsResponse) GlobalTransUtil.getCacheValue(TransCacheConstant.BIZ_RESPONSE);
        scanQrCodeReceiptsResponse = null == scanQrCodeReceiptsResponse ? new ScanQrCodeReceiptsResponse() : scanQrCodeReceiptsResponse;
        scanQrCodeReceiptsResponse.setHeader(scanQrCodeReceiptsRequest.getHeader());
        scanQrCodeReceiptsResponse.setAcqInstCode(mchntInfo.getSignInstId());
        bizResponse.setRspSysId(AppParamConstant.IGAS);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(scanQrCodeReceiptsResponse);
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        ScanQrCodeReceiptsResponse scanQrCodeReceiptsResponse = (ScanQrCodeReceiptsResponse) bizResponse.getResult();
        ConvertUtil.convertInput(scanQrCodeReceiptsResponse);
    }

    /**
     * 获取二维码类型
     *
     * @param request 请求参数
     * @return 二维码产品类型
     * 1、微信付款码 18位纯数字 识别位1-2 识别规则10、11、12、13、14、15
     * 2、支付宝付款码 16-24位的数字 识别位1-2 识别规则25~30
     * 3、QQ钱包付款码 18位数字 识别位1-2 识别规则91
     * 4、京东付款码 17-21 识别位1-2 识别规则62
     * 5、翼支付付款码 18位数字 识别位1-2 识别规则51
     * 6、银联付款码 17-21 识别位1-2 识别规则62
     */
    private String getQrCodeType(ScanQrCodeReceiptsRequest request) throws Exception {
        String payQrCode = request.getPayQrCode();
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        MchntService mchntService = new MchntServiceImpl();
        MchntInfo mchntInfo = mchntService.getMchntInfo(request.getHeader().getInstId(), request.getMchntNo());
        if (null == mchntInfo) {
            rglog.error("获取商户信息失败,mchntNo:<{}>", request.getMchntNo());
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }
        Pattern p = Pattern.compile("^[0-9]*$");
        if (!p.matcher(payQrCode).matches()) {
            rglog.error("二维码号非纯数字:<{}>.", payQrCode);
            return null;
        }
        if (!"".equals(payQrCode.trim()) && 2 < payQrCode.length()) {
            int qrCodePrefix = Integer.parseInt(payQrCode.substring(0, 2));
            if (qrCodePrefix >= 25 && qrCodePrefix <= 30) {
                AlipayMchntInfoMapper alipayMchntInfoMapper = new AlipayMchntInfoMapperImpl();
                AlipayMchntInfo alipayMchntInfo = alipayMchntInfoMapper.selectAlipayMchntInfoByPrimaryKey(mchntInfo.getInstId(), mchntInfo.getMchntNo());
                if (null == alipayMchntInfo
                        || StringUtils.isEmpty(alipayMchntInfo.getAlipayMchntNo())
                        || BspsAppParamConstant.FLAG_N.equals(alipayMchntInfo.getRecordStatus())) {
                    if (MchntTypeEnum.CHAIN_MCHNT_STORE.getMchntType().equals(mchntInfo.getMchntType()) && BspsAppParamConstant.NO.equals(mchntInfo.getIndependentDataFlag())) {
                        rglog.debug("连锁商户门店并且非独立维护商户资料,查询连锁商户的支付宝商户.");
                        alipayMchntInfo = alipayMchntInfoMapper.selectAlipayMchntInfoByPrimaryKey(mchntInfo.getInstId(), mchntInfo.getChainMchntNo());
                    } else {
                        rglog.error("该收款码为支付宝收款码，但商户未开通支付宝商户");
                        throw new BizException(RespCodeEnum.NOT_SUPPORT_ORT_TYPE.getRespCode(), RespCodeEnum.NOT_SUPPORT_ORT_TYPE.getRespDesc());
                    }
                }
                xmlTreeUtil.setXmlTreeObjectValue(BspsTreeNodeConstant.ALI_MCHNT_INFO, alipayMchntInfo);
                return BspsPayTypeEnum.ALIPAY.getPayType();
            } else if (qrCodePrefix >= 10 && qrCodePrefix <= 15) {
                WechatMchntInfoMapper wechatMchntInfoMapper = new WechatMchntInfoMapperImpl();
                WechatMchntInfo wechatMchntInfo = wechatMchntInfoMapper.selectWechatMchntInfoByPrimaryKey(mchntInfo.getInstId(), mchntInfo.getMchntNo());
                if (null == wechatMchntInfo
                        || StringUtils.isEmpty(wechatMchntInfo.getWechatMchntNo())
                        || BspsAppParamConstant.FLAG_N.equals(wechatMchntInfo.getRecordStatus())) {
                    if (MchntTypeEnum.CHAIN_MCHNT_STORE.getMchntType().equals(mchntInfo.getMchntType()) && BspsAppParamConstant.NO.equals(mchntInfo.getIndependentDataFlag())) {
                        rglog.debug("连锁商户门店并且非独立维护商户资料,查询连锁商户的微信商户.");
                        wechatMchntInfo = wechatMchntInfoMapper.selectWechatMchntInfoByPrimaryKey(mchntInfo.getInstId(), mchntInfo.getChainMchntNo());
                    } else {
                        rglog.error("该收款码为微信收款码，但商户未开通微信商户");
                        throw new BizException(RespCodeEnum.NOT_SUPPORT_ORT_TYPE.getRespCode(), RespCodeEnum.NOT_SUPPORT_ORT_TYPE.getRespDesc());
                    }
                }
                xmlTreeUtil.setXmlTreeObjectValue(BspsTreeNodeConstant.WECHAT_MCHNT_INFO, wechatMchntInfo);
                return BspsPayTypeEnum.WECHAT_PAY.getPayType();
            } else if (qrCodePrefix == 91) {
                rglog.error("扫码收款，该收款码为QQ前台付款码，不支持该交易");
                return null;
            } else if (qrCodePrefix == 51) {
                rglog.error("扫码收款，该收款码为翼支付付款码，不支持该交易");
                return null;
            } else if (qrCodePrefix == 62) {
                CupsMchntInfoMapper cupsMchntInfoMapper = new CupsMchntInfoMapperImpl();
                CupsMchntInfo cupsMchntInfo = cupsMchntInfoMapper.selectCupsMchntInfoByPrimaryKey(mchntInfo.getInstId(), mchntInfo.getMchntNo());
                if (null == cupsMchntInfo
                        || BspsAppParamConstant.FLAG_N.equals(cupsMchntInfo.getRecordStatus())) {
                    if (MchntTypeEnum.CHAIN_MCHNT_STORE.getMchntType().equals(mchntInfo.getMchntType()) && BspsAppParamConstant.NO.equals(mchntInfo.getIndependentDataFlag())) {
                        rglog.debug("连锁商户门店并且非独立维护商户资料,查询连锁商户的银联商户.");
                        cupsMchntInfo = cupsMchntInfoMapper.selectCupsMchntInfoByPrimaryKey(mchntInfo.getInstId(), mchntInfo.getChainMchntNo());
                    } else {
                        rglog.error("该收款码为银联收款码，但商户未开通银联商户");
                        throw new BizException(RespCodeEnum.NOT_SUPPORT_ORT_TYPE.getRespCode(), RespCodeEnum.NOT_SUPPORT_ORT_TYPE.getRespDesc());
                    }
                }
                xmlTreeUtil.setXmlTreeObjectValue(BspsTreeNodeConstant.CUPS_MCHNT_INFO, cupsMchntInfo);
                /*处理银联条码，区分借贷记卡，根据二维码类型*/
                /*银联条码，条码第三位可以区分借贷类型，如果数值小于4借记卡，数值大于4是贷记卡*/
                if (new Integer(payQrCode.substring(2, 3)) > 4) {
                    /*银联贷记卡，存内部树,贷记卡生成的二维码*/
                    xmlTreeUtil.setXmlTreeStringValue(BspsTreeNodeConstant.PAYER_ACCT_TYPE, AcctTypeEnum.OTHER_CREDIT.getAcctType());
                } else {
                    /*借记卡生成的银联二维码*/
                    xmlTreeUtil.setXmlTreeStringValue(BspsTreeNodeConstant.PAYER_ACCT_TYPE, AcctTypeEnum.OTHER_DEBIT.getAcctType());
                }
                return BspsPayTypeEnum.CUPS_CLOUD_PAY.getPayType();
            }
        }
        rglog.error("扫码收款失败，二维码为空或长度小于2");
        return null;
    }

    /**
     * 校验业务细分
     *
     * @param qrCodeType 二维码类型
     * @return 业务细分
     */
    private String verifyBizType(String qrCodeType) {
        String bizType;
        if (BspsPayTypeEnum.WECHAT_PAY.getPayType().equals(qrCodeType)) {
            //微信
            bizType = "00";
        } else if (BspsPayTypeEnum.ALIPAY.getPayType().equals(qrCodeType)) {
            //支付宝
            bizType = "01";
        } else {
            //云闪付
            bizType = "02";
        }
        return bizType;
    }

    /**
     * 初始化用户订单信息
     *
     * @param scanQrCodeReceiptsRequest 扫码请求类
     * @param sysSeqNum                 系统流水号
     * @return 用户订单信息
     * @throws Exception 异常
     */
    private UserOrderInfo initUserOrderInfo(ScanQrCodeReceiptsRequest scanQrCodeReceiptsRequest, String sysSeqNum) throws Exception {
        UserOrderInfo userOrderInfo = new UserOrderInfo();
        Header header = scanQrCodeReceiptsRequest.getHeader();
        ConvertUtil.convertOutput(userOrderInfo);
        userOrderInfo.setUserId(scanQrCodeReceiptsRequest.getUserId());
        userOrderInfo.setSysSeqNum(sysSeqNum);
        userOrderInfo.setMsgSrcId(header.getSrcSysId());
        userOrderInfo.setTransChannelId(header.getChanlId());
        userOrderInfo.setUserOrderId(sysSeqNum);
        userOrderInfo.setMchntOrderId(sysSeqNum);
        userOrderInfo.setFrontSeqNum(header.getTraceNo());
        userOrderInfo.setOrderAmt(scanQrCodeReceiptsRequest.getOrderAmt());
        userOrderInfo.setOrderCcy(scanQrCodeReceiptsRequest.getOrderCcy());
        /*待支付金额,若商城自行搞营销,值为【orderAmt-商户订单表.订单优惠金额(商城订单优惠金额)】,扫码无商城优惠,故待支付=订单金额*/
        userOrderInfo.setNeedPayAmt(userOrderInfo.getOrderAmt());
        /*实际支付=待支付-通道(微信/支付宝/营销)优惠金额*/
        userOrderInfo.setRealPayAmt(userOrderInfo.getNeedPayAmt());
        Date date = new Date();
        String currentDateTime = DateUtil.getDateByTimeStamp(date.getTime(), "yyyyMMddHHmmss");
        userOrderInfo.setOrderCreateTime(currentDateTime);
        long expiryTime = date.getTime() + BspsAppParamConstant.ORDER_EXPIRY_TIME;
        String orderExpiryTime = DateUtil.getDateByTimeStamp(expiryTime, "yyyyMMddHHmmss");
        userOrderInfo.setOrderExpiryTime(orderExpiryTime);
        userOrderInfo.setOrderStatus(OrderStatusEnum.INIT.getStatus());
        userOrderInfo.setTransStatus(TransStatusEnum.TRANS_INIT.getStatus());
        userOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
        userOrderInfo.setCreateTime(DateUtil.getCurrentDateTime(BspsAppParamConstant.yyyy_MM_dd_HHmmssSSS));
        return userOrderInfo;
    }

    /**
     * 初始化商户订单信息
     *
     * @param scanQrCodeReceiptsRequest 扫码请求类
     * @param sysSeqNum                 系统流水号
     * @return 商户订单信息
     * @throws Exception 异常
     */
    private MchntOrderInfo initMchntOrderInfo(ScanQrCodeReceiptsRequest scanQrCodeReceiptsRequest, String sysSeqNum) throws Exception {
        MchntOrderInfo mchntOrderInfo = new MchntOrderInfo();
        ConvertUtil.convertOutput(mchntOrderInfo);
        MchntService mchntService = new MchntServiceImpl();
        MchntInfo mchntInfo = mchntService.getMchntInfo(scanQrCodeReceiptsRequest.getHeader().getInstId(), scanQrCodeReceiptsRequest.getMchntNo());
        if (null == mchntInfo) {
            rglog.error("获取商户信息失败,mchntNo:<{}>", scanQrCodeReceiptsRequest.getMchntNo());
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }
        //商户收款扫码(用户被扫)  渠道交易权限配置表
        mchntOrderInfo.setBizProdCode(txnInfo.getSrcTxnAuthCfg().getBizProdCode());
        mchntOrderInfo.setTermNo(scanQrCodeReceiptsRequest.getPayQrCode());
        mchntOrderInfo.setUserId(scanQrCodeReceiptsRequest.getUserId());

        mchntOrderInfo.setSysSeqNum(sysSeqNum);
        mchntOrderInfo.setMchntOrderId(sysSeqNum);
        mchntOrderInfo.setAcqInstCode(mchntInfo.getSignInstId());
        mchntOrderInfo.setIndustryType(mchntInfo.getIndustryType());
        mchntOrderInfo.setMchntNo(scanQrCodeReceiptsRequest.getMchntNo());
        mchntOrderInfo.setMchntName(mchntInfo.getMchntName());
        mchntOrderInfo.setOrderAmt(scanQrCodeReceiptsRequest.getOrderAmt());
        mchntOrderInfo.setOrderCcy(scanQrCodeReceiptsRequest.getOrderCcy());
        mchntOrderInfo.setOrderDiscountAmt("0.00");
        mchntOrderInfo.setRealSettleAmt(scanQrCodeReceiptsRequest.getOrderAmt());
        if (MchntTypeEnum.CHAIN_MCHNT_STORE.getMchntType().equals(mchntInfo.getMchntType())) {
            mchntOrderInfo.setChainMchntNo(mchntInfo.getChainMchntNo());
        }
        /*暂记*/
        mchntOrderInfo.setRealSettleFlag(AppParamConstant.NO);

        mchntOrderInfo.setTxnDate(DateUtil.getCurrentDate());
        mchntOrderInfo.setTxnTime(DateUtil.getCurrentTime());
        mchntOrderInfo.setCreateTime(DateUtil.getCurrentDateTime(BspsAppParamConstant.yyyy_MM_dd_HHmmssSSS));
        mchntOrderInfo.setTransStatus(TransStatusEnum.TRANS_INIT.getStatus());
        mchntOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
        return mchntOrderInfo;
    }

    @Override
    public ChannelCallCfg channelCallSceneDiscern(Object request, List<ChannelCallCfg> channelCallCfgList) throws Exception {
        /* 业务细分：bizType：00-微信条码支付，01-支付宝条码支付，02-银联二维码条码支付 */
        Optional<ChannelCallCfg> channelCallCfgOpt = channelCallCfgList.stream().filter(item ->
                item.getBizScene().equals(ShareParamConstant.CALL_CFG_DEFAULT_BIZ_SCENE)).findFirst();
        return channelCallCfgOpt.orElse(null);
    }

    @Override
    public CheckResultEnum channelCallPreCheck(Object request, ChannelCallCfg channelCallCfg, OrderInfo orderInfo) throws Exception {
        /* 支付结果查询，先判断订单状态是否为处理中 */
        if ("0001".equals(channelCallCfg.getCallIndex())) {
            Optional<PayOrderInfo> payOrderInfoOpt = orderInfo.getPayOrderInfoList().stream().filter(item ->
                    item.getMsgDstId().equals(ChannelEnum.UPWX.getChannelType()) || item.getMsgDstId().equals(ChannelEnum.NUWX.getChannelType()) ||
                            item.getMsgDstId().equals(ChannelEnum.WXZF.getChannelType()) || item.getMsgDstId().equals(ChannelEnum.UPAL.getChannelType()) ||
                            item.getMsgDstId().equals(ChannelEnum.NUAL.getChannelType()) || item.getMsgDstId().equals(ChannelEnum.ALIP.getChannelType()) ||
                            item.getMsgDstId().equals(ChannelEnum.UPQC.getChannelDesc())).findFirst();
            if (payOrderInfoOpt.isPresent()) {
                if (payOrderInfoOpt.get().getBizStatus().equals(BizStatusEnum.PROCESSING.getStatus())) {
                    return CheckResultEnum.PASSED;
                } else {
                    return CheckResultEnum.NEXT;
                }
            } else {
                return CheckResultEnum.NEXT;
            }
        } else {
            return CheckResultEnum.PASSED;
        }
    }

    @Override
    public TransStatusEnum channelCallResultProc(Object request, ChannelCallCfg channelCallCfg, TransStatusEnum transStatusEnum, Object channelResponse, OrderInfo needUpdateOrderInfo) throws Exception {
        if (TransStatusEnum.TRANS_SUCC.equals(transStatusEnum)) {
            ScanQrCodeReceiptsResponse scanQrCodeReceiptsResponse = (ScanQrCodeReceiptsResponse) GlobalTransUtil.getCacheValue(TransCacheConstant.BIZ_RESPONSE);
            if (null == scanQrCodeReceiptsResponse) {
                scanQrCodeReceiptsResponse = new ScanQrCodeReceiptsResponse();
            }
            Optional<PayOrderInfo> payOrderInfoOpt = needUpdateOrderInfo.getPayOrderInfoList().stream().filter(item ->
                    item.getMsgDstId().equals(channelCallCfg.getCallChannelId()) && item.getDstCallIndex().equals(channelCallCfg.getCallIndex())).findFirst();
            if (payOrderInfoOpt.isPresent()) {
                OrderInfoBean orderInfo = new OrderInfoBean();
                BeanUtil.beanCopy(payOrderInfoOpt.get(), orderInfo);
                BeanUtil.nullValueCopy(payOrderInfoOpt.get(), orderInfo);
                scanQrCodeReceiptsResponse.setOrderInfo(orderInfo);
            }
            if (ChannelEnum.UPWX.getChannelType().equals(channelCallCfg.getCallChannelId()) ||
                    ChannelEnum.NUWX.getChannelType().equals(channelCallCfg.getCallChannelId()) ||
                    ChannelEnum.WXZF.getChannelType().equals(channelCallCfg.getCallChannelId())) {
                Result<WechatMicropayResponse> callResult = (Result<WechatMicropayResponse>) channelResponse;
                if (null != callResult && null != callResult.getResult()) {
                    WechatMicropayResponse wechatMicropayResponse = callResult.getResult();
                    if (!StringUtil.isEmptyOrNull(wechatMicropayResponse.getTimeEnd())) {
                        scanQrCodeReceiptsResponse.setSettleDate(wechatMicropayResponse.getTimeEnd().substring(0, 8));
                        payOrderInfoOpt.ifPresent(payOrderInfo -> payOrderInfo.setSettleDate(wechatMicropayResponse.getTimeEnd().substring(0, 8)));
                    }
                }
            } else if (ChannelEnum.UPAL.getChannelType().equals(channelCallCfg.getCallChannelId()) ||
                    ChannelEnum.NUAL.getChannelType().equals(channelCallCfg.getCallChannelId()) ||
                    ChannelEnum.ALIP.getChannelType().equals(channelCallCfg.getCallChannelId())) {
                cc.rengu.igas.channel.alipay.facade.result.Result<AliMircopayResponse> callResult = (cc.rengu.igas.channel.alipay.facade.result.Result<AliMircopayResponse>) channelResponse;
                if (null != callResult && null != callResult.getResult()) {
                    AliMircopayResponse aliMircopayResponse = callResult.getResult();
                    if (!StringUtil.isEmptyOrNull(aliMircopayResponse.getPayTime())) {
                        scanQrCodeReceiptsResponse.setSettleDate(aliMircopayResponse.getPayTime().substring(0, 8));
                        payOrderInfoOpt.ifPresent(payOrderInfo -> payOrderInfo.setSettleDate(aliMircopayResponse.getPayTime().substring(0, 8)));
                    }
                }
            } else if (ChannelEnum.UPQC.getChannelType().equals(channelCallCfg.getCallChannelId())) {
                cc.rengu.igas.channel.upqc.facade.result.Result<C2BConsumeResponse> callResult = (cc.rengu.igas.channel.upqc.facade.result.Result<C2BConsumeResponse>) channelResponse;
                C2BConsumeResponse c2BConsumeResponse = callResult.getResult();
                scanQrCodeReceiptsResponse.setSettleDate(c2BConsumeResponse.getSettleDate());
                payOrderInfoOpt.ifPresent(payOrderInfo -> payOrderInfo.setChannelReconKey(c2BConsumeResponse.getSettleKey()));
                payOrderInfoOpt.ifPresent(payOrderInfo -> payOrderInfo.setSettleDate(c2BConsumeResponse.getSettleDate()));
            }
            GlobalTransUtil.setCacheValue(TransCacheConstant.BIZ_RESPONSE, scanQrCodeReceiptsResponse);
        }
        return transStatusEnum;
    }
}
